# pokedex.py
"""
Pokedex Module

This module contains the Pokedex class and related functions for the Pokémon guessing game.

POKEDEX_GEN: I Gen
VERSION: 1.0
"""

import random

#Class that contains the Pokédex used for the program to choose a Pokémon
#Pokédex is organized as follows: Pokemon, Type, Gen

class Pokedex:
    def __init__(self):
        self.pokedex = [
            ["Bulbasaur", "Grass/Poison", 1],
            ["Ivysaur", "Grass/Poison", 1],
            ["Venusaur", "Grass/Poison", 1],
            ["Charmander", "Fire", 1],
            ["Charmeleon", "Fire", 1],
            ["Charizard", "Fire/Flying", 1],
            ["Squirtle", "Water", 1],
            ["Wartortle", "Water", 1],
            ["Blastoise", "Water", 1],
            ["Caterpie", "Bug", 1],
            ["Metapod", "Bug", 1],
            ["Butterfree", "Bug/Flying", 1],
            ["Weedle", "Bug/Poison", 1],
            ["Kakuna", "Bug/Poison", 1],
            ["Beedrill", "Bug/Poison", 1],
            ["Pidgey", "Normal/Flying", 1],
            ["Pidgeotto", "Normal/Flying", 1],
            ["Pidgeot", "Normal/Flying", 1],
            ["Rattata", "Normal", 1],
            ["Raticate", "Normal", 1],
            ["Spearow", "Normal/Flying", 1],
            ["Fearow", "Normal/Flying", 1],
            ["Ekans", "Poison", 1],
            ["Arbok", "Poison", 1],
            ["Pikachu", "Electric", 1],
            ["Raichu", "Electric", 1],
            ["Sandshrew", "Ground", 1],
            ["Sandslash", "Ground", 1],
            ["Nidoran♀", "Poison", 1],
            ["Nidorina", "Poison", 1],
            ["Nidoqueen", "Poison/Ground", 1],
            ["Nidoran♂", "Poison", 1],
            ["Nidorino", "Poison", 1],
            ["Nidoking", "Poison/Ground", 1],
            ["Clefairy", "Fairy", 1],
            ["Clefable", "Fairy", 1],
            ["Vulpix", "Fire", 1],
            ["Ninetales", "Fire", 1],
            ["Jigglypuff", "Normal/Fairy", 1],
            ["Wigglytuff", "Normal/Fairy", 1],
            ["Zubat", "Poison/Flying", 1],
            ["Golbat", "Poison/Flying", 1],
            ["Oddish", "Grass/Poison", 1],
            ["Gloom", "Grass/Poison", 1],
            ["Vileplume", "Grass/Poison", 1],
            ["Paras", "Bug/Grass", 1],
            ["Parasect", "Bug/Grass", 1],
            ["Venonat", "Bug/Poison", 1],
            ["Venomoth", "Bug/Poison", 1],
            ["Diglett", "Ground", 1],
            ["Dugtrio", "Ground", 1],
            ["Meowth", "Normal", 1],
            ["Persian", "Normal", 1],
            ["Psyduck", "Water", 1],
            ["Golduck", "Water", 1],
            ["Mankey", "Fighting", 1],
            ["Primeape", "Fighting", 1],
            ["Growlithe", "Fire", 1],
            ["Arcanine", "Fire", 1],
            ["Poliwag", "Water", 1],
            ["Poliwhirl", "Water", 1],
            ["Poliwrath", "Water/Fighting", 1],
            ["Abra", "Psychic", 1],
            ["Kadabra", "Psychic", 1],
            ["Alakazam", "Psychic", 1],
            ["Machop", "Fighting", 1],
            ["Machoke", "Fighting", 1],
            ["Machamp", "Fighting", 1],
            ["Bellsprout", "Grass/Poison", 1],
            ["Weepinbell", "Grass/Poison", 1],
            ["Victreebel", "Grass/Poison", 1],
            ["Tentacool", "Water/Poison", 1],
            ["Tentacruel", "Water/Poison", 1],
            ["Geodude", "Rock/Ground", 1],
            ["Graveler", "Rock/Ground", 1],
            ["Golem", "Rock/Ground", 1],
            ["Ponyta", "Fire", 1],
            ["Rapidash", "Fire", 1],
            ["Slowpoke", "Water/Psychic", 1],
            ["Slowbro", "Water/Psychic", 1],
            ["Magnemite", "Electric/Steel", 1],
            ["Magneton", "Electric/Steel", 1],
            ["Farfetch'd", "Normal/Flying", 1],
            ["Doduo", "Normal/Flying", 1],
            ["Dodrio", "Normal/Flying", 1],
            ["Seel", "Water", 1],
            ["Dewgong", "Water/Ice", 1],
            ["Grimer", "Poison", 1],
            ["Muk", "Poison", 1],
            ["Shellder", "Water", 1],
            ["Cloyster", "Water/Ice", 1],
            ["Gastly", "Ghost/Poison", 1],
            ["Haunter", "Ghost/Poison", 1],
            ["Gengar", "Ghost/Poison", 1],
            ["Onix", "Rock/Ground", 1],
            ["Drowzee", "Psychic", 1],
            ["Hypno", "Psychic", 1],
            ["Krabby", "Water", 1],
            ["Kingler", "Water", 1],
            ["Voltorb", "Electric", 1],
            ["Electrode", "Electric", 1],
            ["Exeggcute", "Grass/Psychic", 1],
            ["Exeggutor", "Grass/Psychic", 1],
            ["Cubone", "Ground", 1],
            ["Marowak", "Ground", 1],
            ["Hitmonlee", "Fighting", 1],
            ["Hitmonchan", "Fighting", 1],
            ["Lickitung", "Normal", 1],
            ["Koffing", "Poison", 1],
            ["Weezing", "Poison", 1],
            ["Rhyhorn", "Ground/Rock", 1],
            ["Rhydon", "Ground/Rock", 1],
            ["Chansey", "Normal", 1],
            ["Tangela", "Grass", 1],
            ["Kangaskhan", "Normal", 1],
            ["Horsea", "Water", 1],
            ["Seadra", "Water", 1],
            ["Goldeen", "Water", 1],
            ["Seaking", "Water", 1],
            ["Staryu", "Water", 1],
            ["Starmie", "Water/Psychic", 1],
            ["Mr. Mime", "Psychic/Fairy", 1],
            ["Scyther", "Bug/Flying", 1],
            ["Jynx", "Ice/Psychic", 1],
            ["Electabuzz", "Electric", 1],
            ["Magmar", "Fire", 1],
            ["Pinsir", "Bug", 1],
            ["Tauros", "Normal", 1],
            ["Magikarp", "Water", 1],
            ["Gyarados", "Water/Flying", 1],
            ["Lapras", "Water/Ice", 1],
            ["Ditto", "Normal", 1],
            ["Eevee", "Normal", 1],
            ["Vaporeon", "Water", 1],
            ["Jolteon", "Electric", 1],
            ["Flareon", "Fire", 1],
            ["Porygon", "Normal", 1],
            ["Omanyte", "Rock/Water", 1],
            ["Omastar", "Rock/Water", 1],
            ["Kabuto", "Rock/Water", 1],
            ["Kabutops", "Rock/Water", 1],
            ["Aerodactyl", "Rock/Flying", 1],
            ["Snorlax", "Normal", 1],
            ["Articuno", "Ice/Flying", 1],
            ["Zapdos", "Electric/Flying", 1],
            ["Moltres", "Fire/Flying", 1],
            ["Dratini", "Dragon", 1],
            ["Dragonair", "Dragon", 1],
            ["Dragonite", "Dragon/Flying", 1],
            ["Mewtwo", "Psychic", 1],
            ["Mew", "Psychic", 1]]
    
    #Function used to look for the type and generation of the Pokémon chosen by the user
    def searchPokemonByName(self, pokemon_name):
        pokemon_name_capitalize = pokemon_name.capitalize()
        for pokemon in self.pokedex:
            if pokemon[0] == pokemon_name_capitalize:
                return pokemon
        return None

def checkPrediction(instance_pokedex, chosen_pokemon, prediction):

    name_pokemon, type_pokemon, gen_pokemon = chosen_pokemon

    #Performs a function call to look for the user's Pokémon at Pokédex. And saves the result in a variable
    prediction_pokemon = instance_pokedex.searchPokemonByName(prediction)

    #Check if the user's guess is correct
    #If not, check if the type or generation of the Pokémon chosen by the user, is the same as the Pokémon chosen by the program
    if prediction_pokemon:
        name_pokemon_prediction, type_pokemon_prediction, gen_pokemon_prediction = prediction_pokemon
        if name_pokemon_prediction.capitalize() == name_pokemon.capitalize():
            return f"\n\tCongratulations! You Gotcha!🎉\n\t⬩Pokémon: {name_pokemon}\n\t⬩Type: {type_pokemon}\n\t⬩Gen: {gen_pokemon}\n"
        elif type_pokemon_prediction.capitalize() == type_pokemon.capitalize():
            return f"\n\t❖ {name_pokemon_prediction} has the same type as the chosen Pokémon. ❖"
        elif gen_pokemon_prediction  == gen_pokemon:
            return f"\n\t❖ {name_pokemon_prediction} is from the same generation as the chosen Pokémon. ❖\n"
    else:
        #Returns a message if the user selected Pokémon is not on Pokédex
        return f"\n\t✕ Pokémon {prediction} not found in PokeDex. Try again!"

def main_menu():
    print("\n     ❭ Pokémon Game Menu ❬  ")
    print(" ╔═══════════════════════════╗")
    print(" ║ 1. ❖ Start Game           ║")
    print(" ║ 2. ❖ Instructions         ║")
    print(" ║ 3. ❖ Pokedex              ║")
    print(" ║ 4. ❖ Quit                 ║")
    print(" ╚═══════════════════════════╝")
    choice = input("\nEnter your choice (1, 2, 3, or 4): ")
    return choice

def displayInstructions():
            print(" ╔═════════════════════════════════════╗")
            print(" ║ \t❖ Instructions ❖               ║")
            print(" ║ - Guess the name of a Pokémon!      ║")
            print(" ║ - You have 10 attempts.             ║")
            print(" ║ - If you guess correctly, you win!  ║")
            print(" ║ - Have fun!                         ║")
            print(" ╚═════════════════════════════════════╝")

def displayPokedex(instance_pokedex):
    print("\n\t══════Pokedex══════")
    for pokemon in instance_pokedex.pokedex:
        print(f" {pokemon[0].capitalize()} - Type: {pokemon[1].capitalize()} - Generation: {pokemon[2]}")
    print("\t════════════════════")

#Function that defines the attempts and the main loop of the game
def playGame(instance_pokedex):
    attempts = 10
    chosen_pokemon = random.choice(instance_pokedex.pokedex)

    while attempts >= 1:
        prediction = input("\nChoose the name of a Pokémon: ")
        result = checkPrediction(instance_pokedex, chosen_pokemon, prediction)

        attempts -= 1
        print(f"\nRemaining attempts: {attempts}")

        print(result)

        if "Congratulations!" in result:
            break
    
    if attempts == 0:
        print(f"\n\n🔴You have reached the attempted limit.🔴\n\n\t❖ The correct Pokémon was: {chosen_pokemon[0]} ❖")
